﻿<!DOCTYPE html>
<html>
<head>
<!--
  Copyright (c) 2015-2018 Jean-Marc VIGLINO,
  released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
-->
  <title>ol-ext: Timeline control</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <meta name="description" content="A control to add timeline on a map." />
  <meta name="keywords" content="ol, timeline, control, date" />

  <!-- jQuery -->
  <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>

  <!-- Openlayers -->
  <link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" />
  <script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
  <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
  
  <!-- ol-ext -->
  <link rel="stylesheet" href="../../dist/ol-ext.css" />
  <script type="text/javascript" src="../../dist/ol-ext.js"></script>

  <link rel="stylesheet" href="../style.css" />

  <style>
    .ol-attribution {
      bottom: 6.5em;
      transition: .3s;
    }
    .noimg .ol-attribution {
      bottom: 0.5em;
    }
    
    .ol-timeline img {
      max-height: 2.2em;
      float: left;
      margin: .1em .5em .1em .1em
    };
  </style>

</head>
<body >
  <a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>

  <a href="../../index.html">
    <h1>ol-ext: Timeline control</h1>
  </a>
  <div class="info">
      The <i>ol/control/Timeline</i> displays a timeline to navigate on the map.
      <ul>
        <li>
          Use the <i>getFeatureDate</i> and <i>endFeatureDate</i> option to define the start and end date of the features.
        </li>
        <li>
          Use the <i>getHTMl</i> option to format the contents in the timeline.
        </li>
        <li>
          Use the <i>ol-zoomhover</i> class name to add a zoom effect on hover.
        </li>
        <li>
          When a feature is clicked on the timeline a <i>select</i> event is fired on the control.
        </li>
        <li>
          You can center a date on the line using the <i>setDate()</i> method.
        </li>
        <li>
          Use the <i>getDate()</i> method to get the current date.
        </li>
        <li>
          Listen to the <i>scroll</i> event to know when the line scrolls
        </li>
      </ul>
      <p>
        You can use the Timeline <a href="./map.control.timeinterval.html"> to filter features using a time interval</a>
        <br/>
        or <a href="./map.control.timequake.html">as a time slider to display chronological sequences on a map.</a>
      </p>
  </div>

  <!-- Map div -->
  <div id="map" style="width:600px; height:400px;"></div>

  <div class="options">
    <h2>Options:</h2>
    <button onclick="tline.toggle()">Toggle</button>
    <p>Cureent date: <span class='date'></span></p>
  </div>

  <script type="text/javascript">

  // Two base layers
  var stamen = new ol.layer.Tile({
    title: "Watercolor",
    baseLayer: true,
    source: new ol.source.Stamen({
      layer: 'watercolor'
    })
  });

  // Style function
  var cache = {};
  function style(select){
    return function(f) {
      var style = cache[f.get('img')+'-'+select];
      if (!style) {
        var img = new ol.style.Photo({
          src: f.get('img'),
          radius: select ? 20:15,
          shadow: true,
          stroke: new ol.style.Stroke({
            width: 4,
            color: select ? '#fff':'#fafafa'
          }),
          onload: function() { f.changed(); }
        })
        style = cache[f.get('img')+'-'+select] = new ol.style.Style({
          image: img
        })
      }
      return style;
    }
  };
  
  // GeoJSON layer with a preview attribute
  var vectorSource = new ol.source.Vector({
    url: '../data/fond_guerre.geojson',
    projection: 'EPSG:3857',
    format: new ol.format.GeoJSON(),
		attributions: [ "&copy; <a href='https://data.culture.gouv.fr/explore/dataset/fonds-de-la-guerre-14-18-extrait-de-la-base-memoire'>data.culture.gouv.fr</a>" ],
    logo:"https://www.data.gouv.fr/s/avatars/37/e56718abd4465985ddde68b33be1ef.jpg" 
  });
  var listenerKey = vectorSource.on('change', function(e) {
    if (vectorSource.getState() == 'ready') {
      ol.Observable.unByKey(listenerKey);
      tline.refresh();
    }
  });
  var vector = new ol.layer.Vector({
    name: '1914-18',
    preview: "http://www.culture.gouv.fr/Wave/image/memoire/2445/sap40_z0004141_v.jpg",
    source: vectorSource,
    style: style()
  });


  // The map
  var map = new ol.Map ({
    target: 'map',
    view: new ol.View ({
      zoom: 6,
      center: [173664, 6166327]
    }),
    layers: [stamen, vector]
  });

  // Create Timeline control when features are loaded
  var tline = new ol.control.Timeline({
    className: 'ol-zoomhover',
    source: vectorSource,
    graduation: 'day', // 'month'
    zoomButton: true,
    getHTML: function(f){
      return '<img src="'+f.get('img')+'"/> '+(f.get('text')||'');
    },
    getFeatureDate: function(f) {
      return f.get('date');
    },
    endFeatureDate: function(f) {
      var d = f.get('endDate');
      // Create end date
      if (!d) {
        d = new Date (f.get('date')); 
        d = new Date( d.getTime() + (5 + 10*Math.random())*10*24*60*60*1000);
        f.set('endDate', d);
      }
      return d;
    }
  });
  map.addControl (tline);

  // Select a feature
  tline.on('select', function(e){
    // Center map on feature
    map.getView().animate({
      center: e.feature.getGeometry().getCoordinates(),
      zoom: 10
    });
    // Center time line on feature
    tline.setDate(e.feature);
    // Select feature on the map
    select.getFeatures().clear();
    select.getFeatures().push(e.feature);
  });
  // Collapse the line
  tline.on('collapse', function(e) {
    if (e.collapsed) $('#map').addClass('noimg')
    else $('#map').removeClass('noimg')
  });
  // >croll the line
  tline.on('scroll', function(e){
    $('.options .date').text(e.date.toLocaleDateString());
  });

  var select = new ol.interaction.Select({ hitTolerance: 5, style: style(true) });
  map.addInteraction(select);
  select.on('select', function(e){
    var f = e.selected[0];
    if (f) {
      tline.setDate(f);
    }
  });

  </script>
  
</body>
</html>